var STORE_NAME = "zencontact";

// Change this to set the URL of tha manifest file, which describe which
// URLs to capture. It can be relative to the current page, or an
// absolute URL.
var MANIFEST_FILENAME = "manifest.json";

var localServer;
var store;
var db;


  var blobsAdd = [];
  var blobsEdit = [];
  var blobsDelete = [];

var request = google.gears.factory.create('beta.httprequest');
var PING_TIMEOUT_SECONDS = 1*1000;  
var TIME_BETWEEN_PINGS = 3*1000; 

function init(){
       if (!window.google || !google.gears){
       		alert("Sorry, but you cannot use funtionalities of this website. To fix this problem, plz download Google Gears"); 
       		window.location = "http://gears.google.com/";
       		return;
       }else{
       		loadPingOnlineTest();
       		document.getElementById('debug').innerHTML =  "<img src=\"images/roller.gif\"><b>Downloading data</b>";
         	initializeDB();
         	createStore();
         	synchronizeDB();
       }
	   showQueued();
}


// Test if the browser is connected to the Internet
function online(){
     return navigator.onLine;
     // && (request.responseText != "" && request.responseText.indexOf("404 Page not found") == -1);
}
// Trigger a timer which call this function every second in order to test if request has succeeded
function loadPingOnlineTest(){ 
    var resource_to_test = "test.jsp";    
    request.open('GET', resource_to_test);  
    window.setTimeout("updateOnlineStatus()",PING_TIMEOUT_SECONDS);  
    request.send();
    window.setTimeout("loadPingOnlineTest()",TIME_BETWEEN_PINGS);
}

// Display connectivity status
function updateOnlineStatus() {
    if(online()){
      document.getElementById('connexionStatus').innerHTML = "<img src=\"images/icon_online.png\"> Server Online";
      PostToServer();
    } else {    
      document.getElementById('connexionStatus').innerHTML = "<img src=\"images/icon_offline.png\"> Server Offline";  
    }
  }

// Create the local database if not exists
// 1. One stores all customers (same data as the one stored on the server)
// 2. The other one stores the queuing customer
function initializeDB()  {
     
  try {
       db =  google.gears.factory.create('beta.database', '1.0');
     } catch (ex) {
       alert('Could not create database: ' +  ex.message);
     }

  if (db) {
       db.open('gears');
       if(!db.execute('SELECT id FROM localContact'))
       		db.execute('CREATE VIRTUAL TABLE localContactSearch USING fts2(id, firstName, lastName, email)');
       if(db.execute('CREATE TABLE IF NOT EXISTS localContact ( id int, firstName varchar(255), lastName varchar(255), email varchar(255), notes varchar(255), language varchar(255), category varchar(255), active bool, birthDate Date)'))
       if(db.execute('CREATE TABLE IF NOT EXISTS datablobs ( id_contact int, status int )'))
       localServer = google.gears.factory.create("beta.localserver");
     }
}

// Synchronization process: get customers from MySQL DB hosted on remote server
// This function should be called while page is loading
function synchronizeDB(){
      if(online())
      {
      // Prototype.ps method
      //textConsole("Starting synchronization...");
      var id, name, firstName,lastName,email,notes,language,category,active,birthDate;
      new Ajax.Request('contacts.jsp',
		{
			method: 'get', 
			onSuccess: function(transport){
				var contactTags = transport.responseXML.getElementsByTagName('contact');
				
				for(var i=0; i<contactTags.length ;i++){
					id = parseInt(contactTags[i].getAttribute("id"));
					lastName = contactTags[i].getAttribute("lastname");
					firstName = contactTags[i].getAttribute("firstname");		
					email=contactTags[i].getAttribute("email");		
       				language=contactTags[i].getAttribute("language");
       	      		category=contactTags[i].getAttribute("category");
					notes=contactTags[i].getAttribute("notes");
       	      		if(contactTags[i].getAttribute("active")!=0)
               			active = true;
               		else
               			active = false;
               		birthDate = contactTags[i].getAttribute("birthdate");
					// Add data into local DB
				   var rs=db.execute('SELECT id from localContact where id = ?', [ id ]);
				   var found=0;
				   while (rs.isValidRow()) {
				      found++;
  						rs.next();
					}
					rs.close();
         			if(found==0){
         			   //db.execute('BEGIN');				       db.execute('INSERT INTO localContact VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)', [id, firstName, lastName, email, notes, language, category, active, birthDate]);
					   db.execute('INSERT INTO localContactSearch(id,firstName,lastName,email) VALUES(?, ?, ?, ?)', [id, firstName, lastName, email]);
					   //db.execute('COMMIT');
					   }
					}
         			showContacts();
     				document.getElementById('debug').innerHTML =  "<img src=\"images/checkmark.png\"> Synchronization succeeded";
			},
			onError: function(transport){
				document.getElementById('debug').innerHTML =  "Failed to synchronize. Check your internet connectivity.";
			}
		}
	
	);
     //textConsole("Synchronization succeeded: Server DB copied into local SQLite DB.");
     }
     else {
          //alert("Unable to synchronize with remote DB");
         showContacts();
         document.getElementById('debug').innerHTML =  "Failed to synchronize. Check your internet connectivity.";
          }
          
}

// Add customer to the SQLite DB
function addContact( form )
     {
     // Get the form paramaters for processing data
       var pactive = 0;
		 if(form.active.checked)
			 pactive = 1;
       var pfirstname=form.firstName.value;
       var plastname=form.lastName.value;
       var pemail=form.email.value;
       var pnotes=form.notes.value;
       var planguage=form.language.value;
       for(i=0;i<form.category.length;i++){
		 	if(form.category[i].checked)
				pcategory = form.category[i].value;
		 }
       var pbirthDate = form.birthDate.value;
       var pid=form.idContact.value;
      if(online()){
     	//if(navigator.onLine){
     		if(pid!=""){
     			new Ajax.Request('editContact.jsp',
				{
					method: 'post',
					parameters:{
						id: pid,
						active: pactive,
						firstName: pfirstname,
						lastName: plastname,
						email: pemail,
						category: pcategory,
						birthDate: pbirthDate,
						language: planguage,
						notes: pnotes	
				   },
				   onComplete: function(){
						synchronizeDB();
					}
			   }
			   );
			   //db.execute('BEGIN');
			   db.execute('DELETE FROM localContactSearch where id=?', [pid] );
			   db.execute('DELETE FROM localContact where id=?', [pid] );
			   //db.execute('COMMIT');
			}else{
				new Ajax.Request('addContact.jsp',
				{
					method: 'post', 
					parameters:{
						active: pactive,
						firstName: pfirstname,
						lastName: plastname,
						email: pemail,
						category: pcategory,
						birthDate: pbirthDate,
						language: planguage,
						notes: pnotes	
					},
					onComplete: function(){
						synchronizeDB();
					}
				}
				);
			}
		}
		else
		{
			if(pid==""){
         	pid=0;
         	var rs=db.execute('SELECT id FROM localContact ORDER BY id');
         	while(rs.isValidRow())
         	{
         		pid=rs.field(0);
         		rs.next();
         	}
         	rs.close();
         	pid++;
         	//db.execute('BEGIN');
         	db.execute('INSERT INTO localContactSearch(id,firstName,lastName,email) VALUES (?,?, ?, ?)', [pid, pfirstname, plastname, pemail]);
       		db.execute('INSERT INTO localContact VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', [pid, pfirstname, plastname, pemail, pnotes, planguage, pcategory, pactive, pbirthDate]);
		 	db.execute('INSERT INTO datablobs VALUES (?, ?)', [pid, 0]);
		 	//db.execute('COMMIT'); 
			showQueued();
		 } else {
		    //db.execute('BEGIN');
		 	db.execute("UPDATE localContact SET firstName=?, lastName=?, email=?, notes=?, language=?, category=?, active=?, birthDate=? WHERE id=?",[pfirstname, plastname, pemail, pnotes, planguage, pcategory, pactive, pbirthDate, pid ]);
            db.execute("UPDATE localContactSearch SET firstName=?, lastName=?, email=? WHERE id=?",[pfirstname, plastname, pemail, pid]);
            db.execute('INSERT INTO datablobs VALUES (?, ?)', [pid, 1]);
            //db.execute('COMMIT');
			showQueued();
         }
		}
		 document.getElementById('listContacts').innerHTML="<table id=\"tableContacts\"></table>";
		 showContacts();
     }
     

// Remove all customers info stored into local SQLite DB
function reset(){
   var rs = db.execute( 'DELETE FROM localContact' );
   var rs = db.execute( 'DELETE FROM localContactSearch' );
   showContacts();
}
   
// Update the table displaying all customers
function showContacts(){
     // Empty tableCustomers
     while( document.getElementById('tableContacts').rows.length > 0 )
      document.getElementById('tableContacts').deleteRow( -1 );
      
	var keyWord=document.getElementById("searchString");
	if(keyWord.value!="")
     	var rs=db.execute( 'select id,firstName, lastName, email from localContact where id in (SELECT id FROM localContactSearch WHERE localContactSearch MATCH ?)', [keyWord.value+'*']  );
     else
     	var rs=db.execute( 'select id,firstName, lastName, email from localContact'  );
     while (rs.isValidRow())
     {
     // Handle table functionnalities
       var TR =  document.getElementById('tableContacts').insertRow( -1 );
       TR.onmouseover = function() {  this.style.background = '#eee'; };
       TR.onmouseout = function() {  this.style.background = 'none'; };
       var TD = TR.insertCell( -1 );

         //TD.id = rs.field( 0 );
         //TD.onmouseup = function() { showArticle(  this.id ); };
		 var rs2=db.execute('select id_contact from datablobs where id_contact =?',[rs.field(0)]);
       if(rs2.isValidRow())
       	TD.innerHTML = "<img src=\"images/icon_error.png\">&nbsp;- &nbsp;";
       else
       	TD.innerHTML = "<img src=\"images/icon_valid.png\">&nbsp;- &nbsp;";
       rs2.close();
       TD.innerHTML += rs.field(1)+" "+rs.field(2);
       var TD = TR.insertCell( -1 );
		 TD.innerHTML = "<a href=\"mailto:"+rs.field(3)+"\">"+rs.field(3)+"</a>";
       var TD = TR.insertCell( -1 );
       TD.innerHTML = "<b><a onClick=\"displayEditForm("+rs.field(0)+")\">edit</a> &nbsp;|&nbsp;<a onClick=\"deleteContact("+rs.field(0)+")\">delete</a></b>"; 
       rs.next();
     }
     rs.close();
}

function showQueued()
{
  var rs = db.execute( 'select count(*) from datablobs' );
  while( rs.isValidRow() ) {
    $('result').innerHTML = rs.field(0)+' records queued';    rs.next();
  }
  rs.close();
  var rs = db.execute( 'select * from datablobs' );
  var i=0;
  while( rs.isValidRow() ) {
  i++;
    $('result').innerHTML += '<br> Contact n°'+i+': '+rs.field(0)+" "+rs.field(1);  
      rs.next();
  }
  rs.close();
}



function PostToServer() {
    //textConsole("Test Connectivity for synchronization");
    if(online()){
            startPosting();
    } else
            alert("Unable to post to server. Please check your Internet connectivity.");
}

// According to status, call add,edit or delete.jsp
//
function startPosting()
{  
  var rs = db.execute( 'select id_contact, status from datablobs' );
  var found=0;
  while ( rs.isValidRow() ) {
       document.getElementById('debug').innerHTML =  "<img src=\"images/roller.gif\"><b>Updating data</b>"; 
  		switch(rs.field(1)){
  			case 0:		blobsAdd.push( rs.field(0) );
  				break;
  			case 1:		blobsEdit.push( rs.field(0) );
  				break;
  			case 2:		blobsDelete.push( rs.field(0) );
    			break;
    	}
    	rs.next();
    	found++;
  }
  rs.close();
  if(found!=0){
  		db.execute( 'delete from datablobs' );
  		postData();
  		showContacts(); 
  }
  document.getElementById('debug').innerHTML =  "<img src=\"images/checkmark.png\">Synchronization succeeded";
	
}

function postData( )
{
  while( blobsAdd.length != 0 ) {
  	var id=blobsAdd.pop();
  	var rs = db.execute( 'select * from localContact where id=?',[id] );
  	while ( rs.isValidRow() ) {
  		new Ajax.Request('addContact.jsp',
				{
					method: 'post', 
					parameters:{
						firstName: rs.field(1),
						lastName: rs.field(2),
						email: rs.field(3),
						notes: rs.field(4),	
						language: rs.field(5),
						category: rs.field(6),
						active: rs.field(7),
						birthDate: rs.field(8)
					},
					onSuccess: function() { 
						//textConsole('Contact '+rs.field(2)+' modified into server DB');
						db.execute( 'DELETE FROM localContact WHERE id=?',[id] );
						db.execute( 'DELETE FROM localContactSearch WHERE id=?',[id] );
						showQueued(); 
					}
				}
				);
		rs.next();
	}
	rs.close();
  }
  
  while( blobsEdit.length != 0 ) {
   var id=blobsEdit.pop();
	var rs = db.execute( 'select * from localContact where id=?',[id] );
 	while ( rs.isValidRow() ) {
  		new Ajax.Request('editContact.jsp',
				{
					method: 'post', 
					parameters:{
						id: rs.field(0),
						firstName: rs.field(1),
						lastName: rs.field(2),
						email: rs.field(3),
						notes: rs.field(4),	
						language: rs.field(5),
						category: rs.field(6),
						active: rs.field(7),
						birthDate: rs.field(8)
				   },
				   onSuccess: function() { 
						//textConsole('Contact '+rs.field(2)+' added to server DB');
						db.execute( 'DELETE FROM localContact WHERE id=?',[id] );
						db.execute( 'DELETE FROM localContactSearch WHERE id=?',[id] );;
				   		showQueued();
				    }
			   }
			   );
		rs.next();
	}
	rs.close();
  }
  
  while( blobsDelete.length != 0 ) {
      var params="id="+blobsDelete.pop();
		new Ajax.Request('deleteContact.jsp',
			{
				method: 'post', 
				parameters: params
			}
	
		);
      showQueued();
  }
  synchronizeDB();
}

// Create the managed resource store
function createStore() {
  
  // Open an existing ManagedResourceStore or creates a new one if no such store exists.
  store = localServer.createManagedStore(STORE_NAME);
  store.manifestUrl = MANIFEST_FILENAME;
  store.checkForUpdate();
  //textConsole("Files transfering into the local cache.");
 // Call a function every 500 ms that test whether the files have been transfered
  var timerId = window.setInterval(function() {
    // When the currentVersion property has a value, all of the resources
    // listed in the manifest file for that version are captured. There is
    // an open bug to surface this state change as an event.
    if (store.currentVersion) {
      window.clearInterval(timerId);
      //textConsole("The documents are now available offline.<br/>" +
      //				"The version stored is: " + 
      //        store.currentVersion);
    }
    else {
        switch(store.updateStatus)
        {
            case 0: document.getElementById('debug').innerHTML =  "Last update succeeded";
            break;
            case 1: document.getElementById('debug').innerHTML =  "<img src=\"images/roller.gif\">Checking files to transfer";
            break;
            case 2: document.getElementById('debug').innerHTML =  "<img src=\"images/roller.gif\">Downloading files";
            break;
            case 3: document.getElementById('debug').innerHTML =  "Transfer failed";
        		break;
        }
    }
  }, 500);  
}


// Remove the managed resource store.
function removeStore() {
  // Remove a ManagedResourceStore and all of its contained URLs from the local cache.
  localServer.removeManagedStore(STORE_NAME);
  //textConsole("Done. The local store has been removed.");
}

function textConsole(msg){
	document.getElementById('status').innerHTML += "<br/>"+msg;
}

function deleteContact(id){
	if(online()){
	//if(navigator.onLine){
		var params="id="+id;
		new Ajax.Request('deleteContact.jsp',
			{
				method: 'post', 
				parameters: params
			}
	
		);
	   db.execute( 'DELETE FROM localContact WHERE id=?',[id] );
	   db.execute( 'DELETE FROM localContactSearch WHERE id=?',[id] );
	}
	else
	{
	   db.execute('INSERT INTO datablobs VALUES (?, ?)', [id, 2]);
      db.execute( 'DELETE FROM localContact WHERE id = ?', [ id ] );
      db.execute( 'DELETE FROM localContactSearch WHERE id = ?', [ id ] );
	   showQueued();
	}
	showContacts();
}

function displayEditForm(id){
	
	var rs = db.execute( 'select * from localContact  where id = ?', [ id ] );
   var found = 0;
   while (rs.isValidRow()){
		document.getElementById('listContacts').innerHTML = formAddContact(id,rs.field(1),rs.field(2),rs.field(3),rs.field(4),rs.field(5),rs.field(6),rs.field(7),rs.field(8))
		found++;
		rs.next();
	}
	if(found==0)
		document.getElementById('listContacts').innerHTML = formAddContact("","","","","","","","","")

	rs.close();
}

function cancelModification(){
	document.getElementById('listContacts').innerHTML="<table id=\"tableContacts\"></table>";
	showContacts();
}

function formAddContact(id,firstName,lastName,email,notes,language,category,active,birthDate){
	var contactForm="<form id=\"form\" METHOD=\"POST\">"+
						"<table cellspacing=\"5\">"+
						"<tr>"+ 		
						"<td><message key=\"label.active\">Active contact</message></td>"+
						"<td><input id=\"active\" type=\"checkbox\" ";			
   // Caution: as JavaScript is a non-typed language, check string instead of boolean	
	if(active=="true")
		contactForm += "checked"; 
	contactForm += "/></td>"+
	"</tr>"+
	"<tr>"+
		"<td><message key=\"label.firstname\">First Name</message></td>"+
		"<td><input id=\"firstName\" type=\"text\"  value=\""+firstName+"\"/></td>"+
	"</tr>"+
	"<tr>"+
		"<td><message key=\"label.name\">Last Name</message></td>"+
		"<td><input id=\"lastName\" type=\"text\" value=\""+lastName+"\"/></td>"+
	"</tr>"+
	"<tr>"+
		"<td><message key=\"label.bithdate\">Birthdate</message></td>"+
		"<td><input type=\"text\" size=\"10\" id=\"birthDate\" value=\""+birthDate+"\"/><img id=\"calendar_img\" src=\"images/calendar_icon_1.gif\" onClick=\"GetDate(birthDate);\"/></td>"+
	"</tr>"+
	"<tr>"+
		"<td><message key=\"label.email\">Email</message></td>"+
		"<td><input id=\"email\" type=\"text\" size=\"40\" value=\""+email+"\"/></td>"+
	"</tr>"+
	"<tr>"+
		"<td><message key=\"label.category\">Category</message></td>"+
		"<td NOWRAP>";
	if(category=="Professional")
			contactForm += "<input type=\"radio\" value=\"Professional\" checked name=\"category\"/>Professional <input type=\"radio\" value=\"Personal\" name=\"category\"/>Personal";
	else
			contactForm += "<input type=\"radio\" value=\"Professional\" name=\"category\"/>Professional <input type=\"radio\" value=\"Personal\" checked name=\"category\"/>Personal";

	contactForm += "</td>"+
	"</tr>"+
	"<tr>"+
		"<td><message key=\"label.langues\">Language</message></td>"+
		"<td>";
		contactForm += listLanguages(language);
	contactForm +=	"</td>"+
	"</tr>"+
	"<tr>"+
		"<td valign=\"top\"><message key=\"label.notes\">Notes</message></td>"+
		"<td><textarea id=\"notes\" rows=\"4\" cols=\"40\">"+notes+"</textarea></td>"+
	"</tr>"+
	"<tr>"+
		"<td>&nbsp;</td>"+
		"<td>&nbsp;</td>"+
	"</tr>"+
	"<tr>"+
		"<td colspan=\"3\" align=\"center\">"+
			"<input id=\"save\"	type=\"button\" value=\"Save\" class=\"button\" onClick=\"addContact(this.form)\"/>"+
			"<input id=\"cancel\" type=\"button\" value=\"Cancel\" class=\"button\" onClick=\"cancelModification()\"/>"+
		"</td>"+
	"</tr>"+
"</table>"+
"<input type=\"hidden\" id=\"idContact\" value=\""+id+"\">"+
"</form>";
return contactForm;
}

function listLanguages(language){
		var list="<select id=\"language\" name=\"language\">"+
		"<option value=\"00\">Faites votre choix...</option>";
		if(language=="Anglais")
			list +="<option value=\"Anglais\" selected>Anglais</option>";
		else
			list +="<option value=\"Anglais\">Anglais</option>";
	   if(language=="Francais")
			list +="<option value=\"Francais\" selected>Francais</option>";
		else
			list +="<option value=\"Francais\">Francais</option>";
		if(language=="Italien")
			list +="<option value=\"Italien\" selected>Italien</option>";
		else
			list +="<option value=\"Italien\">Italien</option>";
		if(language=="Allemand")
			list +="<option value=\"Allemand\" selected>Allemand</option>";
		else
			list +="<option value=\"Allemand\">Allemand</option>";
		if(language=="Espagnol")
			list +="<option value=\"Espagnol\" selected>Espagnol</option>";
		else
			list +="<option value=\"Espagnol\">Espagnol</option>";
		list +="</select>";
		return list;
}

